home *** CD-ROM | disk | FTP | other *** search
- *****************************************************************************
- *** Program : TEXT2DBF Copyright (c) BITwise Computer Services, 1992 ***
- *** Date : 08/31/92 ***
- *** Author : David W. Christian ***
- *** Purpose : General purpose Text file to .DBF file conversion program ***
- *** Notes : compile with /n /w ***
- *****************************************************************************
- *** REVISIONS: ***
- *** ***
- *****************************************************************************
-
-
- #include "basic.ch"
- #include "fileio.ch"
- #define LINEBUFF 1024
- #define CRLF CHR(13)+CHR(10)
-
-
- STATIC lEof:=.F.
-
- FUNCTION TEXT2DBF(cSource,cDest,cCDF)
- LOCAL aDestStruc:={}, nX:=0, nSource:=0, nDest:=0, aStruc:={}, ;
- nRow:=0, nCol:=0, cFldList:="", cField:="", cType:="", nLen:=0, ;
- nDec:=0, bBlock, nRet:=0
- MEMVAR cExp, cRec, nCnt
- PRIVATE cExp:="", cRec:="", nCnt:=0
-
- ? "TEXT2DBF 1.0 Copyright (C) BITwise Computer Services, 1992."
- // CHECK SYNTAX
- IF cSource<>NIL .AND. cDest<>NIL .AND. cCDF<>NIL
- IF FILE(cSource)
-
- // READ FORMAT FILE AND LOAD DESTINATION STRUCTURE ARRAY
- cCDF+=IIF(AT(".",cCDF)>0,"",".CDF") // ADD DEFAULT EXTENSION
- IF FILE(cCDF)
- IF ( nSource:=FOPEN(cCDF,FO_READ) ) <>-1
- lEof:=.F.
- nCnt:=0
- ? "Processing CDF..."
- DO WHILE nRet==0 .AND. !lEof
- nCnt++
- cRec:=UPPER(P_READLN(nSource,LINEBUFF)) // READ A LINE
- IF !EMPTY(cRec) .AND. !LTRIM(cRec)="*"
- // PARSE ARRAY COMPONENTS
- cField:=P_PARSE(@cRec)
- cType :=P_PARSE(@cRec)
- nLen :=ABS(VAL(P_PARSE(@cRec)))
- nDec :=ABS(VAL(P_PARSE(@cRec)))
- cExp:=P_PARSE(@cRec)
-
- // CHECK FOR ERRORS IN FIELD DEFINITION
- nRet:=-1
- DO CASE
- CASE cField$cFldList
- P_ERRORMSG("ERROR Duplicate field name "+cField+" - "+cCDF+" line "+STR(nCnt,3))
- CASE P_BADFIELD(cField)
- P_ERRORMSG("ERROR Illegal field name "+cField+" - "+cCDF+" line "+STR(nCnt,3))
- CASE LEN(cType)<>1 .OR. !cType$"CNDLM"
- P_ERRORMSG("ERROR Invalid field type - "+cCDF+" line "+STR(nCnt,3))
- CASE ( nLen==0 ) .OR. ;
- ( cType=="C" .AND. nLen>65536 ) .OR. ;
- ( cType=="N" .AND. nLen>30 ) .OR. ;
- ( cType=="D" .AND. nLen<>8 ) .OR. ;
- ( cType=="L" .AND. nLen<>1 ) .OR. ;
- ( cType=="M" .AND. nLen<>10 )
- P_ERRORMSG("ERROR Invalid field length - "+cCDF+" line "+STR(nCnt,3))
- CASE ( cType<>"N" .AND. nDec<>0 ) .OR. nDec>16
- P_ERRORMSG("ERROR Invalid field decimals length - "+cCDF+" line "+STR(nCnt,3))
- CASE !TYPE(cExp)$"C~N~D~L~M~UI"
- P_ERRORMSG("ERROR Invalid expression - "+cCDF+" line "+STR(nCnt,3))
- CASE P_BADTYPES(TYPE(cExp),cType)
- P_ERRORMSG("ERROR Type mismatch between field and expression - "+cCDF+" line "+STR(nCnt,3))
- OTHERWISE
- nRet:=0 // NO ERRORS
- ENDCASE
-
- // ADD ELEMENT TO ARRAY
- IF nRet==0
- bBlock:= &("{|cRec| "+cExp+"}")
- AADD(aDestStruc,{cField,cType,nLen,nDec,bBlock})
- cFldList+=cField // ADD FIELD NAME TO LIST
- END
- END
- END
-
- IF nRet<>-1
- // SEE IF DESTINATION FILE OK
- lEof:=.F.
- IF FILE(cDest)
- // DESINATION FILE EXISTS - CHECK STRUCTURE AGAINST ARRAY
- USE (cDest) ALIAS DEST NEW
- aStruc:=DBSTRUCT()
- IF LEN(aStruc)==LEN(aDestStruc)
- FOR nX:=1 TO LEN(aStruc)
- IF !aStruc[nX][1]==aDestStruc[nX][1] .OR. ;
- !aStruc[nX][2]==aDestStruc[nX][2] .OR. ;
- !aStruc[nX][3]==aDestStruc[nX][3] .OR. ;
- !aStruc[nX][4]==aDestStruc[nX][4]
- EXIT
- END
- NEXT
- lEof:=( nX>LEN(aStruc) )
- END
- ELSE // CREATE DESTINATION FILE
- ? "Creating "+cDest+"..."
- DBCREATE(cDest,aDestStruc)
- USE (cDest) ALIAS DEST NEW
- lEof:=.T.
- END
-
- IF lEof
- // DESTINATION FILE OPEN - OPEN SOURCE FILE
- FCLOSE(nSource)
- IF ( nSource:=FOPEN(cSource,FO_READ) ) <>-1
-
- // OK, NOW FOR THE FUN PART - READ EACH RECORD IN
- // SOURCE FILE AND PLACE THE RESULTS OF EACH FIELD
- // CODEBLOCK INTO THE CORRESPONDING DEST FIELD
- ? "Adding Records: "
- nRow:=ROW(); nCol:=COL()
- lEof:=.F.
- nCnt:=0
- DO WHILE !lEof .AND. INKEY()<>K_ESC
- cRec:=P_READLN(nSource,LINEBUFF) // READ A LINE
- IF !lEof
- @ nRow,nCol SAY ++nCnt
- DBAPPEND()
- FOR nX:=1 TO LEN(aDestStruc)
- FIELDPUT(nX,EVAL(aDestStruc[nX][5],cRec))
- NEXT
- END
-
- END
- IF LASTKEY()<>K_ESC
- ? "All done!"
- ELSE
- ? "User abort"
- END
- ELSE
- P_ERRORMSG('error opening "'+cSource+'"')
- END
- ELSE
- P_ERRORMSG('structure of "'+cDest+'" does not match CDF')
- END
- CLOSE dest
- END
- FCLOSE(nSource)
- ELSE
- P_ERRORMSG('error opening "'+cCDF+'"')
- END
- ELSE
- P_ERRORMSG('CDF file "'+cCDF+'" not found')
- END
- ELSE
- P_ERRORMSG('Source file "'+cSource+'" not found')
- END
- ELSE
- ? CHR(7)
- ? "Syntax: TEXT2DBF source dest convert[.CDF]"
- ? " source source file in System Data Format - Ascii file,"
- ? " fixed field positions, records end with CRLF"
- ?
- ? " dest destination dBase III+ compatible file - .DBF extension"
- ? " assumed if not supplied, file will be created from"
- ? " CDF file if not found, otherwise records will be"
- ? " appended into existing file"
- ?
- ? " convert Conversion Definition file (CDF) - defines field "
- ? " structures of destination file and conversion expressions"
- ? " to retrieve and manipulate source data"
- ?
- ? "BITwise Computer Services"
- ? "PO Box 97642"
- ? "Raleigh, NC 27624-7642"
- ? "(919) 676-9727"
- ENDIF
- ?
- RETURN(NIL)
-
-
- FUNCTION P_ERRORMSG(cMsg)
- // SYNTAX: P_ERRORMSG(<expC1>)
- // - BEEPS AND DISPLAYS ERROR MESSAGE cMsg
- ? CHR(7)+cMsg
- RETURN(NIL)
-
-
- FUNCTION P_BADFIELD(cField)
- // SYNTAX: P_BADFIELD(<expC1>)
- // - VALIDATES FIELD NAME cField AND RETURNS .T. IF BAD
- //
- LOCAL lRet:=.F., nPos:=1
- lRet:=( LEN(cField)>10 )
- WHILE !lRet .AND. nPos<=LEN(cField)
- lRet:=!( SUBSTR(cField,nPos,1)$"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+;
- IIF(nPos<>1,"0123456789_","") )
- nPos++
- END
- RETURN(lRet)
-
-
- FUNCTION P_BADTYPES(cExpType,cFldType)
- // SYNTAX: P_BADTYPES(<expC1>,<expC2>)
- // - COMPARES EXPRESSION AND FIELD TYPES
- // - RETURNS .T. IF INCOMPATIBLE
- //
- LOCAL lRet:=.F.
- DO CASE
- CASE cExpType==cFldType
- CASE cExpType=="UI"
- CASE cExpType=="C" .AND. cFldType=="M"
- OTHERWISE
- lRet:=.T.
- ENDCASE
- RETURN(lRet)
-
-
- FUNCTION P_READLN(nHandle,nBuffSize)
- // SYNTAX: <expC1>:=P_READLN(<expN1>,[<expN2>])
- // - RETURNS LINE OF TEXT FROM FILE nHandle
- // - USES A READAHEAD LINE BUFFER OF SIZE nBuffSize FOR SPEED
- // (RECORD LENGTH INCLUDING CRLF MUST NOT EXCEED nBuffSize!)
- // - LINE IS ASSUMED TERMINATED WITH CR/LF PAIR
- // - MOVES POINTER TO START OF NEXT LINE (OR EOF)
- //
- LOCAL cRet:="", cBuff:="", nPos:=0, nEol:=0, nRead:=0
- DEFAULT nBuffSize TO 1024
- cBuff:=SPACE(nBuffSize)
- nPos:=FSEEK(nHandle,0,FS_RELATIVE) // SAVE CURRENT POSITION
- IF ( nRead:=FREAD(nHandle,@cBuff,nBuffSize) ) > 0
- IF ( nEol:=AT(CRLF,SUBSTR(cBuff,1,nRead)) ) == 0
- cRet:=cBuff // LINE OVERFLOW OR EOF() - RETURN ENTIRE BUFFER
- ELSE
- cRet:=SUBSTR(cBuff,1,nEol-1)
- FSEEK(nHandle,nPos+nEol+1,FS_SET)
- END
- ELSE
- lEof:=.T.
- END
- RETURN(cRet)
-
-
- FUNCTION P_PARSE(cStr,cDelim,lTrim)
- // SYNTAX: <expC1>:=P_PARSE(@<expC2>,[<expC3>],[<expL1>])
- // - PARSES LINE cStr AND RETURNS NEXT CHUNK DELIMITED BY cDelim
- // - PARSED TEXT IS RETURNED AND REMOVED FROM cStr (PASSED BY REF)
- // - PARSED TEXT IS ALLTRIM()'ed IF lTrim
- // - NOTE: DELIMITER IS NOT INCLUDED IN RETURN STRING
- // DELIMITER NOT REQUIRED AT END OF cStr
- LOCAL cRet:=cStr, nPos:=0
- DEFAULT cDelim TO "|", lTrim TO .T.
- nPos:=AT(cDelim,cStr)
- IF nPos>0
- cRet:=LEFT(cStr,nPos-1)
- cStr:=SUBSTR(cStr,nPos+LEN(cDelim))
- ELSE
- cStr:="" // ENTIRE LINE PARSED
- ENDIF
- RETURN(IIF(lTrim,ALLTRIM(cRet),cRet))
-
-
-
- ////////////////////////////
- /// CONVERSION FUNCTIONS ///
- ////////////////////////////
-
-
- FUNCTION VALIMPDEC(cNum,nDecimals)
- // SYNTAX: <expN1>:=VALIMPDEC(<expC1>,[<expN2>])
- // - CONVERTS IMPLIED-DECIMAL STRING cNum TO CLIPPER NUMERIC
- // - nDecimals IS NUMBER OF DECIMAL POSITIONS (DEFAULT 2)
- //
- DEFAULT nDecimals TO 2
- RETURN( VAL( STUFF(cNum,LEN(cNum)-(nDecimals-1),0,".") ) )
-
-
- FUNCTION CDATE2DT(cDate,cFormat)
- // SYNTAX: <expD1>:=CDATE2DT(<expC1>,[<expC2>])
- // - CONVERTS DATE STRING cDate TO CLIPPER DATE
- // - cFormat IS DATE STRING FORMAT (DEFAULT "M2D2Y2")
- // - RETURNS EMPTY() DATE IF INVALID FORMAT OR STRING
- // - SAMPLE FORMATS:
- // "M2D2Y2" => "122592" MMDDYY
- // "M2D2Y4" => "12251992" MMDDYYYY
- // "D2M2Y2" => "251292" DDMMYY
- //
- LOCAL cMM:="", cDD:="", cYY:="", nX:=0, cType:="", nLen:=0, nPos:=1
- DEFAULT cFormat TO "M2D2Y2"
- cFormat:=UPPER(cFormat)
- FOR nX:=1 TO 6 STEP 2
- cType:=SUBSTR(cFormat,nX,1)
- nLen:=VAL(SUBSTR(cFormat,nX+1,1))
- DO CASE
- CASE cType=="M"
- cMM:=SUBSTR(cDate,nPos,nLen)
- CASE cType=="D"
- cDD:=SUBSTR(cDate,nPos,nLen)
- CASE cType=="Y"
- cYY:=SUBSTR(cDate,nPos,nLen)
- ENDCASE
- nPos+=nLen
- NEXT
- RETURN(CTOD(cMM+"/"+cDD+"/"+cYY))
-
-
- //EOF
-